﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using MoroMoro.Samples.ToDoList.Application.ToDos;
using MoroMoro.Samples.ToDoList.Domain.ToDos;
using MoroMoro.Samples.ToDoList.Presentation.ErrorMessages;
using MoroMoro.Samples.ToDoList.Presentation.ErrorMessages.ToDos;

namespace MoroMoro.Samples.ToDoList.Presentation.Presenters
{
    partial class ToDoListPresenter
    {
        /// <summary>
        /// ToDo 作成ボタンがクリックされた時の処理を行います。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnCreationButtonClick(object sender, EventArgs e)
        {
            View.ShowCreationView(_facade);
        }

        /// <summary>
        /// ToDo 編集ボタンがクリックされた時の処理を行います。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnEditionButtonClick(object sender, EventArgs e)
        {
            var selectedItems = View.CheckedItems;
            if (selectedItems.Count() != 1)
            {
                View.ShowWarningMessageBox("アイテムを一つ選択してください。");
                return;
            }

            var target = selectedItems.Single();
            View.ShowEditionForm(_facade, target);
        }

        /// <summary>
        /// ToDo 削除ボタンがクリックされた時の処理を行います。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnDeletionButtonClick(object sender, EventArgs e)
        {
            var selectedItems = View.CheckedItems;
            if (selectedItems.Count() == 0)
            {
                View.ShowWarningMessageBox("アイテムが選択されていません。");
                return;
            }
            if (View.ShowOkCancelMessageBox("削除します。") == DialogResult.Cancel)
            {
                return;
            }

            _facade.ExecuteToDoDeletion(
                selectedItems,
                (errors) =>
                {
                    var errorMessage = new EntityDeletionErrorMessage();
                    errors.HandledBy(errorMessage);
                    View.ShowErrorMessageBox(errorMessage);
                });
        }


        /// <summary>
        /// ToDo を着手に進めるボタンがクリックされた時の処理を行います。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnForwadToTouchedButtonClick(object sender, EventArgs e)
        {
            ForwadToAnyState(ToDoState.Touched, "着手します。");
        }

        /// <summary>
        /// ToDo を完了に進めるボタンがクリックされた時の処理を行います。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnForwadToCompletedButtonClick(object sender, EventArgs e)
        {
            ForwadToAnyState(ToDoState.Completed, "完了します。");
        }

        /// <summary>
        /// 指定した状態に ToDo を進めます。
        /// </summary>
        /// <param name="state">遷移先となる状態。</param>
        /// <param name="confirmationMessage">確認メッセージ。</param>
        private void ForwadToAnyState(ToDoState state, string confirmationMessage)
        {
            var selectedItems = View.CheckedItems;
            if (selectedItems.Count() == 0)
            {
                View.ShowWarningMessageBox("アイテムが選択されていません。");
                return;
            }
            if (View.ShowOkCancelMessageBox(confirmationMessage) == DialogResult.Cancel)
            {
                return;
            }
            
            _facade.ExecuteToDoForward(
                selectedItems,
                state,
                (errors) =>
                {
                    var errorMessage = new ToDoForwardErrorMessage();
                    errors.HandledBy(errorMessage);
                    View.ShowErrorMessageBox(errorMessage);
                });
        }


        /// <summary>
        /// ToDo を未着手に戻すボタンがクリックされた時の処理を行います。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnReversionToUntouchedButtonClick(object sender, EventArgs e)
        {
            RevertToAnyState(ToDoState.Untouched, "未着手状態に戻します。");
        }

        /// <summary>
        /// ToDo を着手に戻すボタンがクリックされた時の処理を行います。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnReversionToTouchedButtonClick(object sender, EventArgs e)
        {
            RevertToAnyState(ToDoState.Touched, "着手状態に戻します。");
        }

        /// <summary>
        /// 指定した状態に ToDo を戻します。
        /// </summary>
        /// <param name="state">遷移先となる状態。</param>
        /// <param name="confirmationMessage">確認メッセージ。</param>
        private void RevertToAnyState(ToDoState state, string confirmationMessage)
        {
            var selectedItems = View.CheckedItems;
            if (selectedItems.Count() == 0)
            {
                View.ShowWarningMessageBox("アイテムが選択されていません。");
                return;
            }
            if (View.ShowOkCancelMessageBox(confirmationMessage) == DialogResult.Cancel)
            {
                return;
            }

            _facade.ExecuteToDoReversion(
                selectedItems,
                state,
                (errors) =>
                {
                    var errorMessage = new ToDoReversionErrorMessage();
                    errors.HandledBy(errorMessage);
                    View.ShowErrorMessageBox(errorMessage);
                });
        }
    }
}
